#pragma once
#include <string>
#include <iostream>
#include <algorithm>
#include <fstream>
#include "Log.hpp"

class Util
{

public:
    static bool ReadMessage(const std::string filename, std::string *out)
    {
        LOG_DEBUG << "filename: " << filename;
        std::ifstream reader(filename.c_str(), std::ios_base::in | std::ios_base::binary);
        if (!reader.is_open())
        {
            LOG_ERROR << "Open file failed!";
            return false;
        }
        bool status;
        size_t filesize = FileSize(filename, &status);
        if (!status)
        {
            return false;
        }
        out->resize(filesize);
        reader.read((char *)out->c_str(), out->size());
        reader.close();
        return true;
    }

    static size_t FileSize(const std::string filename, bool *status)
    {
        std::ifstream reader(filename.c_str());
        if (!reader.is_open())
        {
            *status = false;
            return 0;
        }
        reader.seekg(0, reader.end);
        size_t length = reader.tellg();
        reader.seekg(0, reader.beg);
        reader.close();
        *status = true;
        return length;
    }

    static bool FileType(const std::string &uri, std::string *out)
    {
        auto pos = uri.rfind(".");
        if(pos == std::string::npos)
        {
            return false;
        }
        std::string type = uri.substr(pos + 1);
        std::transform(type.begin(), type.end(), type.begin(), ::tolower);
        if(type == "html" || type == "htm" || type == "css")
        {
            *out = "text/" + type;
            return true;
        }
        else if(type == "jpeg" || type == "png")
        {
            *out = "image/" + type;
            return true;
        }
        else
        {
            *out = "application/" + type;
            return true;
        }
        
        return false;
    }

    static std::string DistinguishUerAndPassword(std::string analysis_str, std::string* user_name, std::string* user_password)
    {
        auto pos = analysis_str.find("&");
        if (pos == std::string::npos)
        {
            // 没找到，格式不正确返回相应的退出码
            return "FORMAT_ERROR";
        }
        else
        {
            // 格式正确，读取账号密码
            //  1. 找 user 值
            std::size_t u_start = analysis_str.find("user=");
            if (u_start == std::string::npos)
                return "FORMAT_ERROR";
            std::size_t u_end = analysis_str.find('&', u_start);
            if (u_end == std::string::npos)
                return "FORMAT_ERROR";
            *user_name = analysis_str.substr(u_start + 5, u_end - u_start - 5);

            // 2. 找 pwd 值
            std::size_t p_start = analysis_str.find("pwd=");
            if (u_start == std::string::npos)
                return "FORMAT_ERROR";
            std::size_t p_end = analysis_str.size(); // 后面没有 '&'
            if (u_end == std::string::npos)
                return "FORMAT_ERROR";
            *user_password = analysis_str.substr(p_start + 4, p_end - p_start - 4);
        }
        return "DISTINGUISH_SUCCESS";
    }
};
